package com.hm.ipay.service;


import com.hm.ipay.dao.*;
import com.hm.ipay.domain.GameInstanceInfo;
import com.hm.ipay.domain.GameList;
import com.hm.ipay.domain.GameResult;
import com.hm.ipay.domain.GameStatistical;
import com.hm.ipay.domain.result.ExceptionMsg;
import com.hm.ipay.domain.result.ResponseData;
import com.hm.ipay.domain.result.ResponseDataList;
import com.hm.ipay.entity.*;
import com.hm.ipay.utils.DateUtils;
import com.hm.ipay.utils.Jdpush;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class GameService {

    @Autowired
    UserService userService;

    @Autowired
    GameInstanceMapper gameInstanceMapper;

    @Autowired
    GameParticipateInMapper gameParticipateInMapper;

    @Autowired
    UserAccountMapper userAccountMapper;

    @Autowired
    AccountTransactionRecordMapper transactionRecordMapper;

    @Autowired
    GlobalConfigMapper globalConfigMapper;

    @Autowired
    AccountConversionPlanMapper planMapper;

    public ResponseDataList gameInstanceList(Integer limit, Integer offset) {
        if (StringUtils.isEmpty(limit)) {
            limit = 20;
        }
        if (StringUtils.isEmpty(offset)) {
            offset = 0;
        }
        Map map = new HashMap();
        map.put("limit", limit);
        map.put("offset", offset);
        List<GameInstance> list = gameInstanceMapper.gameInstanceList(map);
        int count = gameInstanceMapper.countAllGame();
        return new ResponseDataList(ExceptionMsg.SUCCESS, limit, offset, count, list);
    }

    public ResponseData getGameInstance(Long id) {
        GameInstanceInfo info = new GameInstanceInfo();
        GameInstance instance = gameInstanceMapper.selectByPrimaryKey(id);
        info.setInstance(instance);
        BigDecimal total = gameParticipateInMapper.totalAmount(id);
        Map map = new HashMap();
        map.put("gameId", id);
        map.put("results", 1);
        int winCount = gameParticipateInMapper.countAllPartByResults(map);
        map.remove("results");
        map.put("userChoice", 0);
        int downCount = gameParticipateInMapper.countAllPartByUserChoice(map);
        map.replace("userChoice", 1);
        int upCount = gameParticipateInMapper.countAllPartByUserChoice(map);
        info.setJackpotAmount(total);
        info.setWinningNumber(winCount);
        info.setDownNumber(downCount);
        info.setUpNumber(upCount);
        info.setTotalNumber(downCount + upCount);
        return new ResponseData(ExceptionMsg.SUCCESS, info);
    }

    public ResponseData addGameInstance(GameInstance instance) {
        Date lotteryTime = instance.getLotteryTime();
        lotteryTime.setHours(lotteryTime.getHours() + 8);
        instance.setLotteryTime(lotteryTime);
        Date startTime = instance.getStartTime();
        Date pushTime = (Date)startTime.clone();
        startTime.setHours(startTime.getHours() + 8);
        instance.setStartTime(startTime);
        gameInstanceMapper.insertSelective(instance);
        // 定时推送
        PushRecord record = new PushRecord();
        String title = instance.getGameTitle();
        String alert = "新游戏上线";
        record.setTitle(title);
        record.setContent(alert);
        record.setScheduleTime(startTime);
        //System.out.println("date" + date);
        int messageId = userService.insertMessage(record);
        Jdpush.gameSchedulePushAll(alert, title, pushTime,"定时推送", String.valueOf(instance.getId()));

        return new ResponseData(ExceptionMsg.SUCCESS);
    }

    public ResponseData setGameInstanceInfo(GameInstance instance) {
        GameInstance ins = gameInstanceMapper.selectByPrimaryKey(instance.getId());
        ins.setResults(instance.getResults());
        if (!StringUtils.isEmpty(instance.getGameTitle())) {
            ins.setGameTitle(instance.getGameTitle());
        }
        if (!StringUtils.isEmpty(instance.getLotteryTime())) {
            Date lotteryTime = instance.getLotteryTime();
            lotteryTime.setHours(lotteryTime.getHours() + 8);
            ins.setLotteryTime(lotteryTime);
        }
        if (!StringUtils.isEmpty(instance.getStartTime())) {
            Date startTime = instance.getStartTime();
            startTime.setHours(startTime.getHours() + 8);
            ins.setStartTime(startTime);
        }
        if (!StringUtils.isEmpty(instance.getConfirmPic())) {
            ins.setConfirmPic(instance.getConfirmPic());
        }
        if (!StringUtils.isEmpty(instance.getConfirmUrl())) {
            ins.setConfirmUrl(instance.getConfirmUrl());
        }
        if (!StringUtils.isEmpty(instance.getConfirmText())) {
            ins.setConfirmText(instance.getConfirmText());
        }
        if (!StringUtils.isEmpty(instance.getGameContent())) {
            ins.setGameContent(instance.getGameContent());
        }
        if (!StringUtils.isEmpty(instance.getDescribe())) {
            ins.setDescribe(instance.getDescribe());
        }
        if (!StringUtils.isEmpty(instance.getTitlePicture())) {
            ins.setTitlePicture(instance.getTitlePicture());
        }
        if (!StringUtils.isEmpty(instance.getDescribUrl())) {
            ins.setDescribUrl(instance.getDescribUrl());
        }
        gameInstanceMapper.updateByPrimaryKeySelective(ins);
        return new ResponseData(ExceptionMsg.SUCCESS);
    }

    /**
     *   用户本次游戏参与信息列表
     */
    public ResponseDataList userPartInlist(Integer limit, Integer offset, Long userId, Long gameId) {
        if (StringUtils.isEmpty(limit)) {
            limit = 10000;
        }
        if (StringUtils.isEmpty(offset)) {
            offset = 0;
        }
        Map map = new HashMap();
        map.put("userId", userId);
        map.put("gameId", gameId);
        List<GameParticipateIn> list = gameParticipateInMapper.selectUserPart(map);
        int count = gameParticipateInMapper.countUserPart(map);
        return new ResponseDataList(ExceptionMsg.SUCCESS, limit, offset, count, list);
    }


    public ResponseData gameBetIn(GameParticipateIn participate) {
        Date now = new Date();
        BigDecimal partInAmount = participate.getPartInAmount();
        UserAccount account = userAccountMapper.selectByPrimaryKey(participate.getUserId());
        BigDecimal minePreTA = account.getBalance();
        GameInstance ins = gameInstanceMapper.selectByPrimaryKey(participate.getGameId());
        Date lotteryTime = ins.getLotteryTime();
        lotteryTime.setHours(ins.getLotteryTime().getHours() - 8);
//        Map map = new HashMap();
//        map.put("userId", participate.getUserId());
//        map.put("gameId", participate.getGameId());
        //int partCount = gameParticipateInMapper.countUserPart(map);
        if (minePreTA.compareTo(partInAmount) < 0) {
            return new ResponseData(ExceptionMsg.BalanceNotEnough);
        } else if (lotteryTime.before(now)) {
            return new ResponseData(ExceptionMsg.GameAlreadyLottery);
        }
//        else if (partCount >= 1) {
//            return new ResponseData(ExceptionMsg.GameAlreadyPart);
//        }
        else {
            account.setBalance(minePreTA.subtract(partInAmount));
            BigDecimal minePostTA = account.getBalance();
            userAccountMapper.updateByPrimaryKeySelective(account);
            AccountTransactionRecord mineRecord = new AccountTransactionRecord();
            mineRecord.setUserId(account.getId());
            mineRecord.setUserName(account.getUserName());
            mineRecord.setTransactionType(3);
            mineRecord.setTransactionAmount(partInAmount);
            mineRecord.setTradeDirection((byte)1);
            mineRecord.setPreTransactionAmount(minePreTA);
            mineRecord.setPostTransactionAmount(minePostTA);
            mineRecord.setFrozenStatus((byte)0);
            transactionRecordMapper.insertSelective(mineRecord);
            gameParticipateInMapper.insertSelective(participate);
            return new ResponseData(ExceptionMsg.SUCCESS);
        }
    }

    public void gameLottery() {
        Date now = new Date();
        //Date now = DateUtils.getSqlDate();
        List<GameInstance> instanceList = gameInstanceMapper.selectByStatus(0);
        for (GameInstance instance : instanceList) {
            Date lotteryTime = instance.getLotteryTime();
            lotteryTime.setHours(instance.getLotteryTime().getHours() - 8);
            if (instance.getResults() != -1 && instance.getStatus() != 1 &&
                    lotteryTime.before(now)) {
                lotteryDistributeNew(instance.getId(), instance.getResults());
                instance.setStatus((byte)1);
                gameInstanceMapper.updateByPrimaryKeySelective(instance);
            }
        }
    }

    private void lotteryDistributeNew(Long gameId, Byte results) {
        GlobalConfig config = globalConfigMapper.selectByPrimaryKey(1L);
        Byte win = results;
        Byte lose;
        if (win == 0) {
            lose = 1;
        } else {
            lose = 0;
        }
        Map losePart = new HashMap();
        losePart.put("gameId", gameId);
        losePart.put("userChoice", lose);
        Map winPart = new HashMap();
        winPart.put("gameId", gameId);
        winPart.put("userChoice", win);
        BigDecimal loseTotal = gameParticipateInMapper.totalAmountByUserChoice(losePart);
        if (loseTotal == null) {
            loseTotal = new BigDecimal(0);
        }
        BigDecimal winTotal = gameParticipateInMapper.totalAmountByUserChoice(winPart);
        if (winTotal == null) {
            winTotal = new BigDecimal(0);
        }
        BigDecimal reward = loseTotal.multiply(BigDecimal.valueOf((double)config.getGameReturnPro() / 100));
        BigDecimal average = new BigDecimal(0);
        if (!reward.equals(BigDecimal.ZERO) && !winTotal.equals(BigDecimal.ZERO)) {
            average = reward.divide(winTotal, RoundingMode.HALF_EVEN); // 奖励基数
        }

        List<GameParticipateIn> gameParticipateIns = gameParticipateInMapper.selectByGameId(gameId);
        UserAccount account = null;
        AccountTransactionRecord mineRecord = null;
        Set<String> partInUserPush = new HashSet<>();
        for (GameParticipateIn participate : gameParticipateIns) {
            if (participate.getUserChoice().equals(results)) { // 用户获胜
                /*  参与用户奖励  */
                account = userAccountMapper.selectByPrimaryKey(participate.getUserId());
                // 开奖推送逻辑
                partInUserPush.add(account.getRegistrationId());
                BigDecimal balance = account.getBalance(); //余额
                BigDecimal lottery = participate.getPartInAmount().add(participate.getPartInAmount().multiply(average));//奖励金额 = 参与金额 + 参与金额 * 奖励基数
                participate.setRewardAmount(lottery);
                BigDecimal newBalance = balance.add(lottery); // 新余额
                account.setBalance(newBalance);
                userAccountMapper.updateByPrimaryKeySelective(account);
                mineRecord = new AccountTransactionRecord();
                mineRecord.setUserId(account.getId());
                mineRecord.setUserName(account.getUserName());
                mineRecord.setTransactionType(3);
                mineRecord.setTransactionAmount(lottery);
                mineRecord.setTradeDirection((byte)0);
                mineRecord.setPreTransactionAmount(balance);
                mineRecord.setPostTransactionAmount(newBalance);
                mineRecord.setFrozenStatus((byte)0);
                transactionRecordMapper.insertSelective(mineRecord);
                participate.setResults((byte)1);
                if (average.compareTo(BigDecimal.ZERO) > 0) {
                    /*  参与用户的二级受益人(上级)奖励  */
                    UserAccount secondary = userAccountMapper.selectByPrimaryKey(account.getSecondaryBeneficiary());
                    if (secondary != null) {
                        BigDecimal sec_balance = secondary.getBalance(); //余额
                        //奖励金额 = 参与用户的奖励金额 * 游戏获胜二级受益人分润比例
                        BigDecimal sec_lottery = lottery.multiply(BigDecimal.valueOf((double)config.getGameReturnSecondary() / 100));
                        BigDecimal sec_newBalance = sec_balance.add(sec_lottery); // 新余额
                        secondary.setBalance(sec_newBalance);
                        userAccountMapper.updateByPrimaryKeySelective(secondary);
                        AccountTransactionRecord sec_mineRecord = new AccountTransactionRecord();
                        sec_mineRecord.setUserId(secondary.getId());
                        sec_mineRecord.setUserName(secondary.getUserName());
                        sec_mineRecord.setTransactionType(2);
                        sec_mineRecord.setTransactionAmount(sec_lottery);
                        sec_mineRecord.setTradeDirection((byte)0);
                        sec_mineRecord.setPreTransactionAmount(sec_balance);
                        sec_mineRecord.setPostTransactionAmount(sec_newBalance);
                        sec_mineRecord.setFrozenStatus((byte)0);
                        sec_mineRecord.setTransactionOpposite(account.getId());
                        transactionRecordMapper.insertSelective(sec_mineRecord);
                    }
                    /*  参与用户的一级受益人(上上级)奖励  */
                    UserAccount primary = userAccountMapper.selectByPrimaryKey(account.getPrimaryBeneficiary());
                    if (primary != null) {
                        BigDecimal pri_balance = primary.getBalance(); //余额
                        //奖励金额 = 参与用户的奖励金额 * 游戏获胜二级受益人分润比例
                        BigDecimal pri_lottery = lottery.multiply(BigDecimal.valueOf((double)config.getGameReturnPrimary() / 100));
                        BigDecimal pri_newBalance = pri_balance.add(pri_lottery); // 新余额
                        primary.setBalance(pri_newBalance);
                        userAccountMapper.updateByPrimaryKeySelective(primary);
                        AccountTransactionRecord pri_mineRecord = new AccountTransactionRecord();
                        pri_mineRecord.setUserId(primary.getId());
                        pri_mineRecord.setUserName(primary.getUserName());
                        pri_mineRecord.setTransactionType(2);
                        pri_mineRecord.setTransactionAmount(pri_lottery);
                        pri_mineRecord.setTradeDirection((byte)0);
                        pri_mineRecord.setPreTransactionAmount(pri_balance);
                        pri_mineRecord.setPostTransactionAmount(pri_newBalance);
                        pri_mineRecord.setFrozenStatus((byte)0);
                        pri_mineRecord.setTransactionOpposite(account.getId());
                        transactionRecordMapper.insertSelective(pri_mineRecord);
                    }
                }
            } else {
                participate.setResults((byte)0);
                /***
                 * 如果输了的人邀请注册app的人数<20 那么邀请玩游戏的人A拿2%UPS积分，邀请A的人B拿1%UPS
                 * 如果输了的人邀请注册app的人数 >=20 <30 那么邀请玩游戏的人A拿3%UPS积分，邀请A的人B拿2%UPS
                 * 如果输了的人邀请注册app的人数 >=30那么邀请玩游戏的人A拿4%UPS积分，邀请A的人B拿3%UPS
                 **/
                // 用户邀请了多少人
                int invite = userAccountMapper.secondaryCount(participate.getUserId());
                int primaryProfits;
                int secondaryProfits;
                if (invite < 20) {
                    secondaryProfits = 2;
                    primaryProfits = 1;
                } else if (invite < 30) {
                    secondaryProfits = 3;
                    primaryProfits = 2;
                } else {
                    secondaryProfits = 4;
                    primaryProfits = 3;
                }
                // 输了的人拿到120% UPS(信用值)积分 (可配置)
                account = userAccountMapper.selectByPrimaryKey(participate.getUserId());
                // 开奖推送逻辑
                partInUserPush.add(account.getRegistrationId());
                BigDecimal credit = account.getCreditBalance();
                BigDecimal lottery = participate.getPartInAmount().multiply(BigDecimal.valueOf((double)config.getLoseReturnPro() / 100));
                BigDecimal newCredit = credit.add(lottery); // 新信用额
                account.setCreditBalance(newCredit);
                userAccountMapper.updateByPrimaryKeySelective(account);
                /* 转换计划 */
                AccountConversionPlan plan = new AccountConversionPlan();
                plan.setUserId(account.getId());
                plan.setBaseAmount(lottery);
                plan.setBalance(lottery);
                plan.setOutProportion(config.getOutProportion());
                plan.setStatus((byte)0);
                plan.setSource((byte)1);
                plan.setOriginalAmount(lottery);
                planMapper.insertSelective(plan);
                /*  参与用户的二级受益人(上级)奖励  */
                UserAccount secondary = userAccountMapper.selectByPrimaryKey(account.getSecondaryBeneficiary());
                if (secondary != null) {
                    BigDecimal sec_credit = secondary.getCreditBalance();
                    BigDecimal sec_lottery = lottery.multiply(BigDecimal.valueOf((double)secondaryProfits / 100));
                    BigDecimal sec_newCredit = sec_credit.add(sec_lottery); // 新信用额
                    secondary.setCreditBalance(sec_newCredit);
                    userAccountMapper.updateByPrimaryKeySelective(secondary);
                    /* 转换计划 */
                    AccountConversionPlan sec_plan = new AccountConversionPlan();
                    sec_plan.setUserId(secondary.getId());
                    sec_plan.setBaseAmount(sec_lottery);
                    sec_plan.setBalance(sec_lottery);
                    sec_plan.setOutProportion(config.getOutProportion());
                    sec_plan.setStatus((byte)0);
                    sec_plan.setSource((byte)1);
                    sec_plan.setOriginalAmount(sec_lottery);
                    planMapper.insertSelective(sec_plan);
                }
                /*  参与用户的一级受益人(上上级)奖励  */
                UserAccount primary = userAccountMapper.selectByPrimaryKey(account.getPrimaryBeneficiary());
                if (primary != null) {
                    BigDecimal pri_credit = primary.getCreditBalance();
                    BigDecimal pri_lottery = lottery.multiply(BigDecimal.valueOf((double)primaryProfits / 100));
                    BigDecimal pri_newCredit = pri_credit.add(pri_lottery); // 新信用额
                    primary.setCreditBalance(pri_newCredit);
                    userAccountMapper.updateByPrimaryKeySelective(primary);
                    /* 转换计划 */
                    AccountConversionPlan pri_plan = new AccountConversionPlan();
                    pri_plan.setUserId(secondary.getId());
                    pri_plan.setBaseAmount(pri_lottery);
                    pri_plan.setBalance(pri_lottery);
                    pri_plan.setOutProportion(config.getOutProportion());
                    pri_plan.setStatus((byte)0);
                    pri_plan.setSource((byte)1);
                    pri_plan.setOriginalAmount(pri_lottery);
                    planMapper.insertSelective(pri_plan);
                }
            }
            participate.setStatus((byte)1);
            gameParticipateInMapper.updateByPrimaryKeySelective(participate);
            Jdpush.gameLotteryPush("您参与的游戏已经开奖", "游戏开奖信息", String.valueOf(gameId), partInUserPush);
        }
    }

    private void lotteryDistribute(Long gameId, Byte results) {
        GlobalConfig config = globalConfigMapper.selectByPrimaryKey(1L);
        Byte win = results;
        Byte lose = results;
        if (win == 0) {
            lose = 1;
        } else {
            lose = 0;
        }
        Map losePart = new HashMap();
        losePart.put("gameId", gameId);
        losePart.put("userChoice", lose);
        Map winPart = new HashMap();
        winPart.put("gameId", gameId);
        winPart.put("userChoice", win);
        BigDecimal loseTotal = gameParticipateInMapper.totalAmountByUserChoice(losePart);
        BigDecimal winTotal = gameParticipateInMapper.totalAmountByUserChoice(winPart);

        BigDecimal reward = loseTotal.multiply(BigDecimal.valueOf((double)config.getGameReturnPro() / 100));
        BigDecimal average = reward.divide(winTotal, RoundingMode.HALF_EVEN); // 奖励基数

        List<GameParticipateIn> gameParticipateIns = gameParticipateInMapper.selectByGameId(gameId);
        UserAccount account = null;
        AccountTransactionRecord mineRecord = null;
        for (GameParticipateIn participate : gameParticipateIns) {
            if (participate.getUserChoice().equals(results)) {
                account = userAccountMapper.selectByPrimaryKey(participate.getUserId());
                BigDecimal balance = account.getBalance(); //余额
                BigDecimal lottery = participate.getPartInAmount().add(participate.getPartInAmount().multiply(average));//奖励金额 = 参与金额 + 参与金额 * 奖励基数
                //BigDecimal lottery = participate.getPartInAmount().multiply(BigDecimal.valueOf(2));//奖励金额
                participate.setRewardAmount(lottery);
                BigDecimal newBalance = balance.add(lottery); // 新余额
                account.setBalance(newBalance);
                userAccountMapper.updateByPrimaryKeySelective(account);
                mineRecord = new AccountTransactionRecord();
                mineRecord.setUserId(account.getId());
                mineRecord.setUserName(account.getUserName());
                mineRecord.setTransactionType(3);
                mineRecord.setTransactionAmount(lottery);
                mineRecord.setTradeDirection((byte)1);
                mineRecord.setPreTransactionAmount(balance);
                mineRecord.setPostTransactionAmount(newBalance);
                mineRecord.setFrozenStatus((byte)0);
                transactionRecordMapper.insertSelective(mineRecord);
                participate.setResults((byte)1);
            } else {
                participate.setResults((byte)0);
            }
            participate.setStatus((byte)1);
            gameParticipateInMapper.updateByPrimaryKeySelective(participate);
        }
    }

    public ResponseDataList gamePartInList(Integer limit, Integer offset, Long gameId) {
        if (StringUtils.isEmpty(limit)) {
            limit = 20;
        }
        if (StringUtils.isEmpty(offset)) {
            offset = 0;
        }
        Map map = new HashMap();
        map.put("limit", limit);
        map.put("offset", offset);
        map.put("gameId", gameId);
        List<GameParticipateIn> list = gameParticipateInMapper.selectByGameIdPaging(map);
        int count = gameParticipateInMapper.countAllPart(gameId);
        return new ResponseDataList(ExceptionMsg.SUCCESS, limit, offset, count, list);
    }

    public ResponseData delGameInstance(Long id) {
        gameInstanceMapper.deleteByPrimaryKey(id);
        return new ResponseData(ExceptionMsg.SUCCESS);
    }

    public ResponseData gameResult(Long userId, Long gameId, Long partInId) {
        GlobalConfig config = globalConfigMapper.selectByPrimaryKey(1L);
        GameResult result = new GameResult();
        int isWin = -1;
        int loseNumber = 0;     // 该用户输了多少次
        int winNumber = 0;     // 该用户赢了多少次
        int totalPartInNum = 0; // 总共参与人数
        BigDecimal totalCost = new BigDecimal(0);      // 合计费用
        int winNum = 0;         // 赢的人数总计
        int loseNum = 0;        // 输的人数总计
        BigDecimal loseCost = new BigDecimal(0);      // 输的合计费用
        BigDecimal loseAmount = new BigDecimal(0); // 失败扣款
        BigDecimal winAmount = new BigDecimal(0); // 获胜奖励
        BigDecimal recoveryAmount = new BigDecimal(0); // 回收金额
        int recoveryPercent = config.getGameReturnComp();            // 回收百分比
        recoveryAmount = recoveryAmount.multiply(BigDecimal.valueOf((double)config.getGameReturnComp() / 100));
        List<GameParticipateIn> list = gameParticipateInMapper.selectByGameId(gameId);
        totalPartInNum = list.size();
        for (int i = 0; i < list.size(); i++) {
            totalCost = totalCost.add(list.get(i).getPartInAmount());
            if (list.get(i).getResults() == 0) {
                loseNum += 1;
                loseCost = loseCost.add(list.get(i).getPartInAmount());
                if (userId.equals(list.get(i).getUserId()) && partInId.equals(list.get(i).getId())) {
                    loseAmount = list.get(i).getPartInAmount();
                    isWin = 0;
                }
            } else if (list.get(i).getResults() == 1) {
                winNum += 1;
                if (userId.equals(list.get(i).getUserId()) && partInId.equals(list.get(i).getId())) {
                    winAmount = list.get(i).getPartInAmount();
                    isWin = 1;
                }
            }
        }
        Map map = new HashMap();
        map.put("userId", userId);
        map.put("results", 0);
        loseNumber = gameParticipateInMapper.countUserPartResult(map);
        map.replace("results", 1);
        winNumber = gameParticipateInMapper.countUserPartResult(map);

        result.setIsWin(isWin);
        result.setLoseNumber(loseNumber);
        result.setWinNumber(winNumber);
        result.setTotalPartInNum(totalPartInNum);
        result.setTotalCost(totalCost);
        result.setWinNum(winNum);
        result.setLoseNum(loseNum);
        result.setLoseCost(loseCost);
        result.setLoseAmount(loseAmount);
        result.setWinAmount(winAmount);
        result.setRecoveryPercent(recoveryPercent);
        result.setRecoveryAmount(recoveryAmount);

        return new ResponseData(ExceptionMsg.SUCCESS, result);
    }

    public ResponseDataList gameInstanceListNew(Integer limit, Integer offset, Long userId, int sortType, int sortDir) {
        GlobalConfig config = globalConfigMapper.selectByPrimaryKey(1L);
        Map map = new HashMap();
        if (StringUtils.isEmpty(limit)) {
            limit = 10000;
        }
        if (StringUtils.isEmpty(offset)) {
            offset = 0;
        }
        map.put("limit", limit);
        map.put("offset", offset);
        // 游戏实例数据
        List<GameInstance> list = gameInstanceMapper.gameInstanceListSort(map);
        int count = list.size();
        // 实际返回数据
        List<GameList> results = new ArrayList<>(count);
        GameInstance current;
        GameList game;
        int exclude = 0;
        for (int i = 0; i < count; i++) {
            game = new GameList();
            current = list.get(i);
            Date startTime = current.getStartTime();
            startTime.setHours(current.getStartTime().getHours() - 8);
            Date current_time = new Date();
            if (current_time.before(startTime)) {
                exclude += 1;
                continue;
            }
            game.setInstance(current);
            List<GameParticipateIn> gameList = gameParticipateInMapper.selectByGameId(current.getId());
            int partInNumer = gameList.size();  // 总参与人数
            int winNum = 0; // 胜者数量
            int is_part = 0;  // 用户是否参与
            BigDecimal totalCost = new BigDecimal(0);      // 合计费用
            BigDecimal winnerEarnings = new BigDecimal(0); // 胜者总收益
            BigDecimal averageEarnings = new BigDecimal(0); // 胜者总收益
            for (int j = 0; j < partInNumer; j++) {
                GameParticipateIn partIn = gameList.get(j);
                totalCost = totalCost.add(partIn.getPartInAmount());
                if (userId.equals(partIn.getUserId())) {
                    is_part = 1;
                }
                if (partIn.getResults() == 0) {
                    winnerEarnings = winnerEarnings.add(partIn.getPartInAmount());
                } else if (partIn.getResults() == 1) {
                    winNum += 1;
                }
            }
            averageEarnings = averageEarnings.multiply(BigDecimal.valueOf((double)config.getGameReturnPro() / 100));
            game.setAverageEarnings(averageEarnings);
            game.setWinnerEarnings(winnerEarnings);
            game.setIsPart(is_part);
            game.setWinNum(winNum);
            game.setPartInNumer(partInNumer);
            game.setTotalCost(totalCost);
            results.add(game);
        }

        // sortDir 0正序  1倒序
        if (sortType == 1) {  // 按交易金额
            results.sort(new Comparator<GameList>() {
                @Override
                public int compare(GameList o1, GameList o2) {
                    if (sortDir == 0) {
                        return o2.getTotalCost().compareTo(o1.getTotalCost());
                    } else {
                        return o1.getTotalCost().compareTo(o2.getTotalCost());
                    }
                }
            });
        } else if (sortType == 2) {  // 按参与人数
            results.sort(new Comparator<GameList>() {
                @Override
                public int compare(GameList o1, GameList o2) {
                    if (sortDir == 0) {
                        return o2.getPartInNumer() - o1.getPartInNumer();
                    } else {
                        return o1.getPartInNumer() - o2.getPartInNumer();
                    }
                }
            });
        } else if (sortType == 0) {  // 按时间
            results.sort(new Comparator<GameList>() {
                @Override
                public int compare(GameList o1, GameList o2) {
                    if (sortDir == 0) {
                        return o2.getInstance().getStartTime().compareTo(o1.getInstance().getStartTime());
                    } else {
                        return o1.getInstance().getStartTime().compareTo(o2.getInstance().getStartTime());
                    }
                }
            });
        }
        return new ResponseDataList(ExceptionMsg.SUCCESS, limit, offset, count - exclude, results);
    }

    public ResponseData getGameInstanceNotPart(Long userId) {
        //
        List<GameInstance> instanceList = gameInstanceMapper.selectByStatus(0);
        Map map = new HashMap();
        map.put("userId", userId);
        map.put("gameId", 0);
        int count = -1;
        for (int i = 0; i < instanceList.size(); i++) {
            Date lotteryTime = instanceList.get(i).getLotteryTime();
            lotteryTime.setHours(instanceList.get(i).getLotteryTime().getHours() - 8);
            Date current_time = new Date();
            if (current_time.after(lotteryTime)) {
                continue;
            }
            map.replace("gameId", instanceList.get(i).getId());
            count = gameParticipateInMapper.countUserPart(map);
            if (count == 0) {
                return new ResponseData(ExceptionMsg.SUCCESS, instanceList.get(i).getId());
            }
        }
        return new ResponseData(ExceptionMsg.SUCCESS, null);
    }

    public ResponseData userGameInfoStatistical(Long userId) {
        Map map = new HashMap();
        map.put("userId", userId);
        map.put("results", -1);
        int activityGame = gameInstanceMapper.countByStatus(0);
        int userPartInGame = gameParticipateInMapper.countUserPartResult(map);
        BigDecimal userWinUpp = gameParticipateInMapper.totalWinAmount(userId);
        BigDecimal userWinUps = planMapper.totalWinUps(userId);
        GameStatistical gameStatistical = new GameStatistical(activityGame, userPartInGame, userWinUpp, userWinUps);
        return new ResponseData(ExceptionMsg.SUCCESS, gameStatistical);
    }
}
